<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <meta http-equiv="X-UA-Compatible" content="ie=edge">
    <title>Document</title>
</head>
<body>
    <canvas  id="canvas" width="600" height="600"></canvas>
</body>

<script>
    let canvas = document.getElementById('canvas')
    let ctx = canvas.getContext('2d')
    
    /* 绘制矩形 */
    /* // ctx.fillStyle = 'rgb(200, 0, 0)'
    // 填充矩形
    ctx.fillRect(25, 25, 100, 100) // 参数分别是 左上角 X 坐标、左上角 Y 坐标、宽度、高度
    // 绘制矩形的边框
    ctx.strokeRect(50, 50, 50, 50)
    // 清除指定矩形区域，让清除部分完全透明
    ctx.clearRect(45, 45, 60, 60) */

    /** 绘制路径 
     * beginPath() 新建一条路径，生成之后，图形绘制命令被指向到路径上生成路径。
     * closePath() 闭合路径之后图形绘制命令又重新指向到上下文中。
     * stroke() 通过线条来绘制图形轮廓
     * fill() 通过填充路径的内容区域生成实心的图形
     * moveTo(x, y) 这个函数实际上并不能画出任何东西,一般设置起点
     */

    // 1、绘制三角形
    /* ctx.beginPath()
    ctx.moveTo(75, 50)
    ctx.lineTo(100, 75)
    ctx.lineTo(100, 25)
    ctx.fill() */

    // 2、运用 moveTo 函数绘制笑脸
    /* ctx.beginPath()
    ctx.arc(75, 75, 50, 0, Math.PI*2, true); // 绘制  参数分别是 圆中心 X 坐标，圆中心 Y 坐标， 半径， 起始角，结束角，顺时针（false）或逆时针（true）
    ctx.moveTo(110, 75);
    ctx.arc(75, 75, 35, 0, Math.PI);   // 口(顺时针)
    ctx.moveTo(65, 65);
    ctx.arc(60 ,65, 5, 0, Math.PI*2);  // 左眼
    ctx.moveTo(95, 65);
    ctx.arc(90, 65, 5, 0, Math.PI*2);  // 右眼
    ctx.stroke(); */

    // 当你调用fill()函数时，所有没有闭合的形状都会自动闭合，所以你不需要调用closePath()函数。但是调用stroke()时不会自动闭合。
    // 3、绘制直线
    /** 
     * lineTo() 绘制一条从当前位置到指定x以及y位置的直线。(坐标系中直线结束的点)
     */
    /* ctx.beginPath()
    ctx.moveTo(0, 0)
    ctx.lineTo(210, 230)
    ctx.closePath()
    ctx.stroke() */

    // 填充颜色
    /* for(let i = 0; i < 6; i++) {
        for (let j = 0; j < 6; j++) {
            ctx.fillStyle = `rgb(${Math.floor(255 - 42.5 * i)}, ${Math.floor(255 - 42.5 * j)}, 0)`
            ctx.fillRect(j * 25, i * 25, 25, 25)
        }
    } */
    
    // 透明度
    /* ctx.fillStyle = '#FD0'
    ctx.fillRect(0, 0, 75, 75)
    ctx.fillStyle = '#6C0'
    ctx.fillRect(75, 0, 75, 75)
    ctx.fillStyle = '#09F'
    ctx.fillRect(0, 75, 75, 75)
    ctx.fillStyle = '#F30'
    ctx.fillRect(75, 75, 75, 75)
    ctx.fillStyle = '#fff'
    // 设置透明度
    ctx.globalAlpha = 0.2
    for(let i = 0; i < 5; i++) {
        ctx.beginPath()
        ctx.arc(75, 75, 10 + 10 * i, 0, Math.PI * 2)
        ctx.fill()
    } */

    // 线型 Line styles

    /* for (let i = 0; i < 10; i++) {
        ctx.lineWidth = i + 1
        ctx.beginPath()
        ctx.moveTo(5 + i * 20, 5)
        ctx.lineTo(5 + i * 20, 100)
        ctx.stroke()
    } */

    // lineCap 线条端点的样式
    /* ctx.strokeStyle = '#09f'
    ctx.beginPath()
    ctx.moveTo(10, 10)
    ctx.lineTo(200, 10)
    ctx.moveTo(10, 100)
    ctx.lineTo(200, 100)
    ctx.stroke()
    let lineCap = ['butt', 'round', 'square']
    ctx.strokeStyle = '#000'
    for (let i = 0; i < lineCap.length; i++) {
        ctx.lineCap = lineCap[i]
        ctx.lineWidth = 15
        ctx.beginPath()
        ctx.moveTo(20 + i * 50, 10)
        ctx.lineTo(20 + i * 50, 100)
        ctx.stroke()
    } */

    // 虚线
    /* let offset = 0
    function draw () {
        ctx.clearRect(0, 0, canvas.width, canvas.height)
        ctx.setLineDash([4, 2]) // 参数 线条长度， 间隔宽度
        ctx.lineDashOffset = -offset
        ctx.strokeRect(10, 10, 100, 100)
    }

    function march () {
        offset++
        if (offset > 16) {
            offset = 0
        }
        draw()
        setTimeout(march, 20);
    }
    march() */

    // 渐变 Gradients
    // 参数 表示渐变的起点 (x1,y1) 与终点 (x2,y2) 线性渐变
    /* let lineGard = ctx.createLinearGradient(0, 0, 0, 150)
    lineGard.addColorStop(0, '#00ABEB') // 参数必须是一个 0.0 与 1.0 之间的数值，表示渐变中颜色所在的相对位置。例如，0.5 表示颜色会出现在正中间, 第二个参数是颜色
    lineGard.addColorStop(0.5, '#fff')
    lineGard.addColorStop(0.5, '#26C000')
    lineGard.addColorStop(1, '#fff')

    ctx.fillStyle = lineGard
    ctx.fillRect(10, 10, 130, 130) */

    // 环形渐变 接受 6 个参数，前三个定义一个以 (x1,y1) 为原点，半径为 r1 的圆，后三个参数则定义另一个以 (x2,y2) 为原点，半径为 r2 的圆。
    /* let radGard = ctx.createRadialGradient(45, 45, 10, 52, 50, 30)
    radGard.addColorStop(0, '#A7D30C')
    radGard.addColorStop(0.9, '#019F62')
    radGard.addColorStop(1, 'rgba(1,159,98,0)')

    ctx.fillStyle = radGard
    ctx.fillRect(0, 0, 150, 150) */

    // 文本
    /* ctx.font = '48px'
    ctx.fillText('Hello World!!!', 10, 50)
    ctx.strokeText('Hello World!!!', 10, 50) */

    // save 和 restore
    /* ctx.fillRect(0, 0, 150, 150)
    ctx.save()
    
    ctx.fillStyle = '#09F'
    ctx.fillRect(15, 15, 120, 120)
    ctx.save()

    ctx.fillStyle = '#fff'
    ctx.globalAlpha = 0.5
    ctx.fillRect(30, 30, 90, 90)

    // 重新加载之前的颜色状态
    ctx.restore() // 相当于拿到上上一次的设置 每 restore 一次，设置就往上层找
    ctx.fillRect(45, 45, 60, 60)

    ctx.restore();
    ctx.fillRect(60,60,30,30); */

    // 行星环绕
    /* var sun = new Image();
    var moon = new Image();
    var earth = new Image();
    function init(){
    sun.src = 'https://mdn.mozillademos.org/files/1456/Canvas_sun.png';
    moon.src = 'https://mdn.mozillademos.org/files/1443/Canvas_moon.png';
    earth.src = 'https://mdn.mozillademos.org/files/1429/Canvas_earth.png';
    window.requestAnimationFrame(draw);
    }

    function draw() {

    ctx.globalCompositeOperation = 'destination-over'; // 在源图像上方显示目标图像。
    ctx.clearRect(0, 0 , canvas.width, canvas.height); // clear canvas

    ctx.fillStyle = 'rgba(0, 0, 0, 0.4)';
    ctx.strokeStyle = 'rgba(0, 153, 255, 0.4)';
    ctx.save();
    ctx.translate(150, 150);

    // Earth
    var time = new Date();
    ctx.rotate(((2 * Math.PI) / 60) * time.getSeconds() + ((2 * Math.PI) / 60000) * time.getMilliseconds() );
    ctx.translate(105, 0);
    ctx.fillRect(0, -12, 50, 24); // Shadow
    ctx.drawImage(earth, -12, -12);

    // Moon
    ctx.save();
    ctx.rotate(((2 * Math.PI) / 6) * time.getSeconds() + ((2 * Math.PI) / 6000) * time.getMilliseconds());
    ctx.translate(0, 28.5);
    ctx.drawImage(moon, -3.5, -3.5);
    ctx.restore();

    ctx.restore();
    
    ctx.beginPath();
    ctx.arc(150,150,105,0,Math.PI*2,false); // Earth orbit
    ctx.stroke();
    
    ctx.drawImage(sun,0,0,300,300);

    window.requestAnimationFrame(draw);
    }

    init(); */

    // 小球
    let raf
    let ball = {
        x: 100,
        y: 100,
        r: 50,
        c: 'blue',
        vx: 5,
        vy: 2,
        draw() {
            ctx.beginPath()
            ctx.arc(this.x, this.y, this.r, 0, Math.PI * 2)
            ctx.closePath()
            ctx.fillStyle = this.c
            ctx.fill()
        }
    }

    // 添加速度
    function draw() {
        // 判断边界
        if(ball.y + ball.vy + 25 > canvas.height || ball.y + ball.vy < 0) {
            ball.vy = -ball.vy
        }
        if(ball.x + ball.vx + 25 > canvas.height || ball.x + ball.vx < 0) {
            ball.vx = -ball.vx
        }
        // 长尾效果
        ctx.fillStyle = 'rgba(255, 255, 255, 0.3)'
        ctx.fillRect(0, 0, canvas.width, canvas.height)
        // ctx.clearRect(0, 0, canvas.width, canvas.height)
        ball.draw()
        ball.x += ball.vx
        ball.y += ball.vy
        raf = window.requestAnimationFrame(draw)
    }

    canvas.addEventListener('mouseover', function(e) {
        raf = window.requestAnimationFrame(draw)
    })
    canvas.addEventListener('mouseout', function(e) {
        window.cancelAnimationFrame(raf)
    })
    ball.draw()
</script>
</html>